﻿using System;
using System.Drawing;
using System.Windows.Forms;
using Simple3DRedactor.Domain;

namespace SceneRedactor
{
    public partial class SimpleSceneRedactor : UserControl
    {
        private SceneView<IRedactorObjectView> _scene;
        private IRedactorObjectView _selectedItem;
        
        public SimpleSceneRedactor()
        {
            InitializeComponent();
        }

        public Scene Scene
        {
            get { return _scene == null ? null : _scene.Scene; }
            set
            {
                list.Items.Clear();

                if (value == null)
                {
                    _scene = null;
                }
                else
                {
                    _scene = new SceneView<IRedactorObjectView>(value, new ObjectViewFactory());

                    _scene.ChildAdd += OnSceneChildAdd;
                    _scene.ChildAssign += OnSceneChildAssign;
                    _scene.ChildChange += OnSceneChildChange;
                    _scene.ChildRemove += OnSceneChildRemove;
                    _scene.ChildsClear += OnSceneChildsClear;

                    foreach (var view in _scene)
                        list.Items.Add(view);
                }
            }
        }

        public event Action<Scene, SceneObject> SelectionChanged;
        public void OnSelectionChanged(SceneObject arg2)
        {
            if (SelectionChanged != null) SelectionChanged(Scene, arg2);
        }

        public SceneObject SelectedObject
        {
            get { return _selectedItem == null ? null : _selectedItem.InnerObject; }
            set
            {
                if (list.SelectedItem != null && ((IRedactorObjectView)list.SelectedItem).InnerObject == value)
                    return;

                foreach (var item in list.Items)
                {
                    var view = (IRedactorObjectView)item;

                    if (view.InnerObject == value)
                    {
                        list.SelectedItem = item;
                        return;
                    }
                }
            }
        }

        private void OnSceneChildAdd(SceneView<IRedactorObjectView> arg1, IRedactorObjectView arg2)
        {
            list.Items.Add(arg2);
        }

        private void OnSceneChildAssign(SceneView<IRedactorObjectView> scene, IRedactorObjectView oldview, IRedactorObjectView newview)
        {
            var ind = list.Items.IndexOf(oldview);
            list.Items[ind] = newview;
        }

        private void OnSceneChildChange(SceneView<IRedactorObjectView> arg1, IRedactorObjectView arg2)
        {
            if (arg2 == _selectedItem)
                _selectedItem.ShowProperties(this);
        }

        private void OnSceneChildRemove(SceneView<IRedactorObjectView> arg1, IRedactorObjectView arg2)
        {
            list.Items.Remove(arg2);
        }

        private void OnSceneChildsClear(SceneView<IRedactorObjectView> obj)
        {
            list.Items.Clear();
            ClearProperties();
        }

        private void ListSelectedIndexChanged(object sender, EventArgs e)
        {
            ClearProperties();

            if (list.SelectedItem == null)
            {
                _selectedItem = null;
                OnSelectionChanged(null);
                return;
            }

            _selectedItem = (IRedactorObjectView)list.SelectedItem;
            _selectedItem.ShowProperties(this);

            OnSelectionChanged(_selectedItem.InnerObject);
        }
        
        private void ClearProperties()
        {
            objectNameTextBox.Text = "";
            objectPositionXTextBox.Text = "";
            objectPositionYTextBox.Text = "";
            objectPositionZTextBox.Text = "";

            SphereAndCylinderPropertiesGroupBox.Visible = false;
            SphereAndCylinderPropertiesGroupBox.Location = new Point(0, 400);
            boxPropertiesGroupBox.Visible = false;
            boxPropertiesGroupBox.Location = new Point(0, 400);
            lightPropertiesGroupBox.Visible = false;
            lightPropertiesGroupBox.Location = new Point(0, 400);
        }

        private void SaveProperiesButtonClick(object sender, EventArgs e)
        {
            if (_selectedItem == null) return;

            _selectedItem.SaveProperties(this);
        }
        
        private void SphereToolStripMenuItemClick(object sender, EventArgs e)
        {
            if (_scene != null)
                _scene.Scene.Add(new Sphere());
        }

        private void boxToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if(_scene!=null)
                _scene.Scene.Add(new Box());
        }

        private void cylinderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if(_scene!=null)
                _scene.Scene.Add(new Cylinder());
        }

        private void lightToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if(_scene!=null)
                _scene.Scene.Add(new Light());
        }

        private void RemoveObjectToolStripMenuItemClick(object sender, EventArgs e)
        {
            if (_selectedItem == null) return;

            _scene.Scene.Remove(_selectedItem.InnerObject);
        }

        private void saveButton_Click(object sender, EventArgs e)
        {
            if(_selectedItem == null) return;

            _selectedItem.SaveProperties(this);
        }

    }
}